import { type RuleItem } from "../tools/rule";
import {
  type RegisteredComponentType,
  type RegisteredChildComponentType,
} from "../tools/componentRegistry";
import { SPECIAL_TYPES } from "../tools/registerElementComponents";
import { type FormProps } from "element-plus";

/** 组件类型联合（内置+自定义） */
export type ComponentType = RegisteredComponentType | typeof SPECIAL_TYPES.slot;

/** 子组件的联合类型 */
export type childrenType = RegisteredChildComponentType;

/** 基础配置 */
interface BaseFormItemConfig {
  /** 组件的label */
  label?: string;
  value?: any;
  /** 占位符(eg:请输入 ) */
  placeholder?: string;
  /** 组件的参数配置 */
  componentProps?: Record<string, any>;
  // 校验规则集成 -el 是基于( async-validator ) 封装的校验规则
  rules?: Array<RuleItem>;
  // 自定义插槽支持
  slotName?: string;
  /** 自定义事件 */
  events?: Record<string, (...args: any[]) => void>;
}

/** 表单项基础配置 */
export interface FormItemConfig extends BaseFormItemConfig {
  /** 组件绑定的属性名 */
  prop: string;
  /** 为哪种类型(组件) */
  type: ComponentType;
  /** 组件的子组件(用于扩展) */
  children?: childrenConfig;
  /** item的label宽度 */
  labelWidth?: string | number;
  /**  是否在行内显示校验信息 */
  inlineMessage?: string | boolean;
  /** 表单item的尺寸 */
  size?: "" | "large" | "default" | "small";
  /** item的宽度 */
  width?: string | number;
}

/** 子组件基础配置 */
export interface childrenConfig extends BaseFormItemConfig {
  /** 子组件类型 */
  type: childrenType;
  /** 用于不用label展示的项 */
  htmlText?: string;

  prop?: string;
  data: Omit<childrenConfig, "type" | "data">[];
}

/** 对外暴露的api */
export interface XFormApiEvents<TFormData extends Record<string, any>> {
  /** 校验表单 */
  validate: (callback: (isValid: boolean, invalidFields?: any) => void) => void;

  resetFields: () => void;
  /** 提交表单事件 */
  submit: () => Promise<TFormData>;
}

// 这个不用动后续添加事件在↑增加即可
export interface XFormApi<
  TFormData extends Record<string, any> = Record<string, any>
> extends XFormApiEvents<TFormData> {
  /**
   * 注册API
   * @param api  参数
   * @returns
   */
  register: (api: XFormApi<TFormData>) => void;

  /** 注册成功之后的事件对象,是ref对象 */
  value?: XFormApiEvents<TFormData>;
}

/**
 * XForm组件的Props类型定义
 */
export interface XFormProps<
  TFormData extends Record<string, any> = Record<string, any>
> extends Partial<FormProps> {
  /** 表单配置 */
  config: FormItemConfig[];
  /** 表单初始值 */
  initialValues: TFormData;
  /** 是否隐藏底部按钮 */
  footerShow?: boolean;
}
